package com.goa.task;

import com.goa.entity.DeviceCron;
import com.goa.mapper.DeviceTaskMapper;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

@Slf4j
@Component  // Spring 管理的组件
public class SchedulerUtil {

    private final Scheduler scheduler;  // Quartz 调度器实例
    private final DeviceTaskMapper deviceTaskMapper;  // 用于获取定时任务的 Mapper

    @Autowired
    public SchedulerUtil(DeviceTaskMapper deviceTaskMapper) throws SchedulerException {
        // 初始化 Scheduler 实例
        this.scheduler = StdSchedulerFactory.getDefaultScheduler();
        this.deviceTaskMapper = deviceTaskMapper;
    }

    @PostConstruct
    public void startScheduler() {
        try {
            // 确保 Scheduler 只启动一次
            if (!scheduler.isStarted()) {
                scheduler.start();
                List<DeviceCron> deviceCrons = deviceTaskMapper.findAll();  // 获取所有的定时任务配置

                // 遍历所有的设备定时任务并添加到调度器
                for (DeviceCron deviceCron : deviceCrons) {
                    addJob(deviceCron);  // 添加每个定时任务到调度器
                }

                log.info("Quartz 调度器已成功启动并加载所有任务.");
            }
        } catch (SchedulerException e) {
            log.error("启动 Quartz 调度器失败", e);
        }
    }

    public Scheduler getScheduler() {
        return scheduler;
    }

    /**
     * 将单个定时任务添加到调度器
     *
     * @param deviceCron 设备定时任务配置
     * @throws SchedulerException 如果任务添加失败
     */
    public void addJob(DeviceCron deviceCron) throws SchedulerException {
        try {
            JobDataMap jobDataMap = new JobDataMap(JobScheduler2a.convertToMap(deviceCron));
            JobDetail jobDetail = JobBuilder.newJob(DynamicJob.class)
                    .withIdentity(deviceCron.getJobName(), "group1")
                    .withDescription(deviceCron.getDescription())
                    .usingJobData("addressIp", deviceCron.getAddressIp())
                    .usingJobData("id", deviceCron.getId())
                    .usingJobData(jobDataMap)
                    .build();

            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(deviceCron.getJobName(), "group1")
                    .withSchedule(CronScheduleBuilder.cronSchedule(deviceCron.getCronExpression()))
                    .build();

            // 将 JobDetail 和 Trigger 添加到调度器中
            scheduler.scheduleJob(jobDetail, trigger);
            log.info("成功添加任务: {}", deviceCron.getJobName());

        } catch (SchedulerException e) {
            log.error("调度任务失败: {}", deviceCron.getJobName(), e);
            throw e;  // 重新抛出异常
        } catch (Exception e) {
            log.error("添加任务时发生错误: {}", deviceCron.getJobName(), e);
            throw new SchedulerException("任务添加失败", e);
        }
    }
}
